package handler

import (
	"fmt"
	"net/http"
	"regexp"

	"github.com/gin-gonic/gin"
	"github.com/juexin/gin-base/internal/service"
	"github.com/juexin/gin-base/pkg/response"
)

type SMSHandler struct {
	smsService *service.SMSService
}

func NewSMSHandler(smsService *service.SMSService) *SMSHandler {
	return &SMSHandler{
		smsService: smsService,
	}
}

// SendVerificationCode 发送验证码
func (h *SMSHandler) SendVerificationCode(c *gin.Context) {
	var req service.SMSRequest

	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数错误: "+err.Error())
		return
	}

	// 验证手机号格式
	if !h.isValidPhone(req.Phone) {
		response.Error(c, http.StatusBadRequest, "手机号格式不正确")
		return
	}

	// 验证用途
	if !h.isValidPurpose(req.Purpose) {
		response.Error(c, http.StatusBadRequest, "无效的验证码用途")
		return
	}

	// 发送验证码
	result, err := h.smsService.SendVerificationCode(&req)
	if err != nil {
		response.Error(c, http.StatusBadRequest, "发送验证码失败: "+err.Error())
		return
	}

	// 构建响应数据
	responseData := map[string]interface{}{
		"phone":       result.Phone,
		"expire_time": result.ExpireTime,
		"is_test":     result.IsTest,
		"request_id":  result.RequestID,
	}

	// 测试模式下返回验证码
	if result.IsTest {
		responseData["code"] = result.Code
	}

	response.SuccessWithMsg(c, "验证码发送成功", responseData)
}

// VerifyCode 验证验证码
func (h *SMSHandler) VerifyCode(c *gin.Context) {
	var req service.VerifyCodeRequest

	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数错误: "+err.Error())
		return
	}

	// 验证手机号格式
	if !h.isValidPhone(req.Phone) {
		response.Error(c, http.StatusBadRequest, "手机号格式不正确")
		return
	}

	// 验证用途
	if !h.isValidPurpose(req.Purpose) {
		response.Error(c, http.StatusBadRequest, "无效的验证码用途")
		return
	}

	// 验证码格式检查
	if !h.isValidCode(req.Code) {
		response.Error(c, http.StatusBadRequest, "验证码格式不正确")
		return
	}

	// 检查剩余尝试次数
	remaining, err := h.smsService.GetRemainingAttempts(req.Phone, req.Purpose)
	if err != nil {
		response.Error(c, http.StatusInternalServerError, "检查尝试次数失败")
		return
	}

	if remaining <= 0 {
		response.Error(c, http.StatusTooManyRequests, "验证失败次数过多，请24小时后再试")
		return
	}

	// 验证验证码
	err = h.smsService.VerifyCode(&req)
	if err != nil {
		// 记录失败尝试
		h.smsService.RecordFailedAttempt(req.Phone, req.Purpose)

		// 更新剩余次数
		remaining--
		if remaining <= 0 {
			response.Error(c, http.StatusTooManyRequests, "验证码错误，已达最大尝试次数，请24小时后再试")
		} else {
			response.Error(c, http.StatusBadRequest, fmt.Sprintf("验证码错误，还有%d次尝试机会", remaining))
		}
		return
	}

	response.SuccessWithMsg(c, "验证码验证成功", map[string]interface{}{
		"phone":   req.Phone,
		"purpose": req.Purpose,
	})
}

// isValidPhone 验证手机号格式
func (h *SMSHandler) isValidPhone(phone string) bool {
	// 中国大陆手机号正则表达式
	phoneRegex := regexp.MustCompile(`^1[3-9]\d{9}$`)
	return phoneRegex.MatchString(phone)
}

// isValidPurpose 验证用途是否有效
func (h *SMSHandler) isValidPurpose(purpose string) bool {
	validPurposes := map[string]bool{
		"register":       true, // 注册
		"login":          true, // 登录
		"reset_password": true, // 重置密码
		"bind_phone":     true, // 绑定手机号
		"change_phone":   true, // 更换手机号
	}

	return validPurposes[purpose]
}

// isValidCode 验证验证码格式
func (h *SMSHandler) isValidCode(code string) bool {
	// 6位数字验证码
	codeRegex := regexp.MustCompile(`^\d{6}$`)
	return codeRegex.MatchString(code)
}
